////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//  Filename:    ElLuchador.h			                                      //
//  Developer:				                                                  //
//  Create date:			                                                  //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//  Description: This is the class declaration for the slot gut of the        //
//               Australian Slot machine called El Luchador			          //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
//        2011 - Riplife Gaming.  All rights reserved.						  //
////////////////////////////////////////////////////////////////////////////////

#if !defined(__ELLUCHADORGUTS_H__)
#define __ELLUCHADORGUTS_H__

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "slotguts.h"
#include "getrand.h"

class ElLuchadorGuts : public SlotGuts
{
public:
	ElLuchadorGuts();

	virtual ~ElLuchadorGuts();

private:
	// Shared enums between client and server
	#include "ElLuchadorCommon.h"

	// Helpful lookup arrays.
	

	static SpinResult m_aLineWinSpinResults[][6];
	static SpinResult m_aScatterWinSpinResults[][6];
	static int8 m_aPayLineOffsets[25][5];

	// Inline functions to use with the arrays that also do
	// bounds checking.
	static SpinResult lookupLineWinSpinResult( uint8 nIconType, uint8 nCount )
	{
		if ( nIconType < NUM_VALID_ICONS && nCount < 6 )
		{
			return m_aLineWinSpinResults[ nIconType ][ nCount ];
		}

		ASSERT( false );
		return EVT_INVALID;
	}

	static SpinResult lookupScatterWinSpinResult( uint8 nIconType, uint8 nCount )
	{
		if ( nIconType < NUM_VALID_ICONS && nCount < 6 )
		{
			return m_aScatterWinSpinResults[ nIconType ][ nCount ];
		}

		ASSERT( false );
		return EVT_INVALID;
	}

	static uint8 getRowLineReel( uint8 Payline, uint8 Reel )
	{
		int offset = m_aPayLineOffsets[ Payline ][ Reel ];
		switch(offset)
		{
		case 1 : return 0;
				 break;
		case 0 : return 1;
				 break;
		case -1 : return 2;
			     break;
		default : return 0;
		}
	}

	void tryForJackpot( SlotSpin* spin );

	SpinResult getScatterWinResult( SlotSpin* spin, uint8 testIcon, int32& scatterPositions ) const;
	
	void evaluateScatterWin( SlotSpin* spin, SpinResult srScatterResult, int32 scatterPositions );

	void resetSubGameValues();

protected:
	//virtual int32 getNumLinesBet();

public:
	
	SpinResult getWildsWinResult( uint8* stops, uint8 line, int32 addedWilds );

    SpinResult getLineWinResultWithPossibleSubstitution( uint8* stops, uint8 line, uint8 testIcon, int32 addedWilds );

		/**
         * @brief Iterate the lines played and determine winners.
         * @param spin the slot spin.
         * @see classifyStops
         */
	void classifyElLuchadorStops( SpinLine* spinline, uint8* stops, uint8 bet, uint8 line, int32 addedWilds, uint8& rtnresult );

	bool doesWildLineWinPayMore( SpinResult srWilds, SpinResult srOther ) const;

    virtual void classifyResult(SlotSpin *spin);

	int32 classifyLuchadorScatters( SlotSpin *spin );

    virtual bool8 isValidGuts();

    virtual void getGameModeMultiplierAndNoteId( uint8& nGameModeMultiplier, uint8& nNoteId );

	virtual bool8 processClientData( uint8 bonusGameType, int32 bonusDataCount, int32 *bonusData );

	virtual bool8 isBonusGameInProgress();


protected:
	// Override these framework functions.
	virtual void preSpinClassifyResults( SlotSpin* spin );
    virtual void postSpinClassifyResults( SlotSpin* spin );

	virtual bool8 hasSavedGames();

	virtual void Debug_SetLoserStops( uint8* pStops );

	int32 getProgressiveValue();

	uint8 evaluateMultiplierFeature();		// Affects current spin, so it is evaluated in preSpin
	int32 evaluateAddedWildsFeature();		// Affects current spin, so it is evaluated in preSpin
	uint8 evaluateCurtainPickFeature();		// Bonus game after the spin, so it is evaluated in postSpin

	int32 getRoundWildsMask(int32 WildsMask, uint8 NumWilds);

	BonusGame* addElLuchadorBonusGame(uint8 bonusgametype,uint8 bonusgameindex,int32 basepayoutamount,int32 totalmultiplier,int32 totalbonuspayoutamount,int32 freespins,int64 overridegamenum = 0,bool8 bSaved = false);

	// Debug functions: all combinations of three different features: AddedWilds feature, Multiplier feature, Curtain feature
	enum
	{
		EVT_DEBUG_ADDWILDS = 401,
		EVT_DEBUG_MULTIPLIER,
		EVT_DEBUG_CURTAIN,
		EVT_DEBUG_ADDWILDS_MULTIPLIER,
		EVT_DEBUG_ADDWILDS_CURTAIN,
		EVT_DEBUG_MULTIPLIER_CURTAIN,
		EVT_DEBUG_ADDWILDS_MULTIPLIER_CURTAIN
	};

	static bool8 bDebugAddWilds;
	static bool8 bDebugMultiplier;
	static bool8 bDebugCurtain;

	virtual void initDebugFunctionMap();

	void Debug_AddWilds( SlotSpin *spin );
	void Debug_Multiplier( SlotSpin *spin );
	void Debug_Curtain( SlotSpin *spin );
	void Debug_AddWilds_Multiplier( SlotSpin *spin );
	void Debug_AddWilds_Curtain( SlotSpin *spin );
	void Debug_Multiplier_Curtain( SlotSpin *spin );
	void Debug_AddWilds_Multiplier_Curtain( SlotSpin *spin );

};  


#endif // !defined(__ELLUCHADORGUTS_H__)
